import GameRule from '../enum/game';
/**
 * @function rewriteJudge 判断胜利者
 * @description 本方法通过从落子位置开始向上下，左右，斜上下(两个方向)进行发散，查找是否可以组成连续的字符串使其等于我们规定最大连通数量，然后进行一个判断。
 * @param {PlayerTarget[]} checkedList 当前游戏网格记录数据
 * @param {Position} currentPosition 当前点击位置信息
 * @returns {JudgeWinnerData} 返回用于判断是否决出胜利者数据
 */
export default function rewriteJudge (checkedList: PlayerTarget[], currentPosition: Position): JudgeWinnerData {
    const listIndex = (currentPosition.column * GameRule.BOARD_ROW) + currentPosition.row;
    const { row, column } = currentPosition;
    const currentTar = checkedList[listIndex];
    /**
     * @property {number} columnCount 竖直方向数量
     * @property {number} rowCount 水平方向数量
     * @property {number} biasCount1 左斜线方向数量
     * @property {number} biasCount2 右斜线方向数量
     */
    let columnStr = '';
    let rowStr = '';
    let biasStr1 = '';
    let biasStr2 = '';

    if (!currentTar) {
        return {
            tar: null,
            end: false,
        };
    }
    const endingTar = currentTar.repeat(GameRule.WINNER_COUNT);
    /**
     * @function judgeRule 判断规则
     */
    function judgeRule (judgeString: string) {
        const filterData = judgeString.split(' ').filter((str: string) => str !== ' ');
        for (const str of filterData) {
            if (str.length >= endingTar.length) return true;
            continue;
        }
        return false;
    }
    /**
     * @function boundary 边界判断
     * @param {number} xStep x轴步长
     * @param {number} yStep y轴步长
     */
    function boundary (xStep: number, yStep: number) {
        return (((row + xStep) >= 0) && ((row + xStep) < GameRule.BOARD_ROW)) && (((column + yStep) >= 0) && ((column + yStep) < GameRule.BOARD_COLUMN));
    }
    for (let step = -GameRule.WINNER_COUNT + 1; step < GameRule.WINNER_COUNT; step++) {
        if (step === 0) {
            columnStr += currentTar;
            rowStr += currentTar;
            biasStr1 += currentTar;
            biasStr2 += currentTar;
            continue;
        }
        // note: 获取各个方向上的标识符
        const rowTar = checkedList[step + listIndex];
        const columnTar = checkedList[(step * GameRule.BOARD_ROW) + listIndex];
        const bias1Tar = checkedList[(((step * -1) * GameRule.BOARD_ROW) + listIndex) + step];
        const bias2Tar = checkedList[(step * GameRule.BOARD_ROW) + listIndex + step];

        rowStr += rowTar === currentTar && boundary(step, 0) ? rowTar : ' ';
        columnStr += columnTar === currentTar && boundary(0, step) ? columnTar : ' ';
        biasStr1 += bias1Tar === currentTar && boundary(step, -step) ? bias1Tar : ' ';
        biasStr2 += bias2Tar === currentTar && boundary(step, step) ? bias2Tar : ' ';
    }
    const status = judgeRule(rowStr) || judgeRule(columnStr) || judgeRule(biasStr1) || judgeRule(biasStr2);

    return {
        tar: status ? checkedList[listIndex] : null,
        end: status,
    };
}
